package com.ng.desktop.expansionsa.view.alquiler;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.BorderFactory;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.view.JRViewer;

import org.apache.commons.lang.StringUtils;

import com.jidesoft.swing.AutoCompletionComboBox;
import com.ng.desktop.expansionsa.model.Alquiler;
import com.ng.desktop.expansionsa.model.Articulo;
import com.ng.desktop.expansionsa.model.Detalle;
import com.ng.desktop.expansionsa.model.EstadoAlquiler;
import com.ng.desktop.expansionsa.model.TipoCliente;
import com.ng.desktop.expansionsa.persistence.AlquilerPersistence;
import com.ng.desktop.expansionsa.persistence.ArticuloPersistence;
import com.ng.desktop.expansionsa.services.NGFactoryBean;
import com.ng.desktop.expansionsa.view.cliente.ClienteSelectorField;
import com.ng.framework.view.desktop.NGDatePicker;
import com.ng.framework.view.desktop.NGEditDialog;
import com.ng.framework.view.desktop.NGGUIUtils;
import com.ng.framework.view.desktop.table.NGCustomTable;
import com.ng.framework.view.desktop.table.NGTableModel;

public class AlquilerEditDialog extends NGEditDialog<Alquiler, AlquilerPersistence> {
	
	private static final long serialVersionUID = 8918278547987394799L;

	private static final int COL_CANT = 0;
	private static final int COL_ARTICULO = 1;
	private static final int COL_DIAS = 2;
	private static final int COL_FECHA_DEVOLUCION = 3;
	private static final int COL_PRECIO = 4;
	private static final int COL_SUB_TOTAL = 5;
	
	private static final String[] COLUMN_NAMES = { "Cant.", "Artículo", "Días", "Fecha de devolución", "Precio", "Sub Total" };
	
	private static final DateFormat FORMATO_FECHA = new SimpleDateFormat("dd/MM/yyyy");
	private static final NumberFormat FORMATO_TOTAL = new DecimalFormat("0.00");
	
	private NGDatePicker datePickerfecha;
	private ClienteSelectorField clienteSelectorField;
	private JTextField textFieldDireccionObra;
	private AutoCompletionComboBox comboBoxEstado;
	private JButton buttonAgregarDetalle;
	private JButton buttonEliminarDetalle;
	private NGCustomTable tableDetalle;
	private JTextField textFieldTotal;
	private JTextArea textAreaObservaciones;
	private JButton buttonImprimirContrato;
	
	private boolean llenando = false;
	private List<Detalle> idsDetalles;
		
	public AlquilerEditDialog(Window owner, AlquilerPersistence persistence) {
		this(owner, persistence, null);
	}

	public AlquilerEditDialog(Window owner, AlquilerPersistence persistence,
			Alquiler instance) {
		super(owner, persistence, instance);
		
		this.setTitle("Gestión de Alquiler");
		this.setSize(new Dimension(800, 500));
	}

	@Override
	protected JPanel createDetailPanel() {
		JPanel detailPanel = new JPanel(new GridBagLayout());
		
		detailPanel.add(new JLabel("Fecha:"), new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
		detailPanel.add(this.getDatePickerFecha(), new GridBagConstraints(1, 0, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 5, 0), 0, 0));
		
		detailPanel.add(new JLabel("Cliente:"), new GridBagConstraints(0, 1, 1, 1, 0, 0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
		detailPanel.add(this.getClienteSelectorField(), new GridBagConstraints(1, 1, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 5, 0), 0, 0));
		
		detailPanel.add(new JLabel("Dirección de la obra:"), new GridBagConstraints(0, 2, 1, 1, 0, 0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
		detailPanel.add(this.getTextFieldDireccionObra(), new GridBagConstraints(1, 2, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 5, 0), 0, 0));
		
		detailPanel.add(this.createPanelDetalle(), new GridBagConstraints(0, 3, 2, 1, 1, 0.75, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 5, 0), 0, 0));
		
		detailPanel.add(new JLabel("Estado:"), new GridBagConstraints(0, 4, 1, 1, 0, 0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
		detailPanel.add(this.getComboBoxEstado(), new GridBagConstraints(1, 4, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 5, 0), 0, 0));
		
		detailPanel.add(new JLabel("Observaciones:"), new GridBagConstraints(0, 5, 1, 1, 0, 0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
		detailPanel.add(new JScrollPane(this.getTextAreaObservaciones(), JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER), new GridBagConstraints(1, 5, 1, 1, 1, 0.25, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 0, 5, 0), 0, 0));
		
		detailPanel.add(this.getButtonImprimirContrato(), new GridBagConstraints(0, 6, 2, 1, 1, 0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
		
		return detailPanel;
	}
	
	private NGDatePicker getDatePickerFecha() {
		if(datePickerfecha == null) {
			datePickerfecha = new NGDatePicker();
			datePickerfecha.setEditable(false);
			datePickerfecha.setMinimumSize(datePickerfecha.getPreferredSize());
			datePickerfecha.getDocument().addDocumentListener(new DocumentListener() {
				
				@Override
				public void removeUpdate(DocumentEvent e) {
				}
				
				@Override
				public void insertUpdate(DocumentEvent e) {
					String textoDatePicker = AlquilerEditDialog.this.getDatePickerFecha().getText();
					if(StringUtils.isNotBlank(textoDatePicker)) {
						try {
							Date fecha = FORMATO_FECHA.parse(textoDatePicker);
							Calendar c = Calendar.getInstance();
							for(int i = 0; i < AlquilerEditDialog.this.getTableDetalle().getRowCount(); i++) {
								Integer dias = (Integer)AlquilerEditDialog.this.getTableDetalle().getValueAt(i, COL_DIAS);
								if(dias != null) {
									c.setTime(fecha);
									c.add(Calendar.DAY_OF_MONTH, dias);
									AlquilerEditDialog.this.getTableDetalle().setValueAt(FORMATO_FECHA.format(c.getTime()), i, COL_FECHA_DEVOLUCION);
								}
								
							}
						} catch (ParseException e1) {
							JOptionPane.showMessageDialog(AlquilerEditDialog.this, "Error al parsear fecha de devolución.", "Error", JOptionPane.ERROR_MESSAGE);
						}	
					}
				}
				
				@Override
				public void changedUpdate(DocumentEvent e) {
				}
			});
		}
		
		return datePickerfecha;
	}
	
	private ClienteSelectorField getClienteSelectorField() {
		if(clienteSelectorField == null) {
			clienteSelectorField = new ClienteSelectorField();
		}
		
		return clienteSelectorField;
	}
	
	private JTextField getTextFieldDireccionObra() {
		if(textFieldDireccionObra == null) {
			textFieldDireccionObra = new JTextField();
		}
		
		return textFieldDireccionObra;
	}

	private NGCustomTable getTableDetalle() {
		if(tableDetalle == null) {
			tableDetalle = new NGCustomTable(COLUMN_NAMES);
			tableDetalle.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
			tableDetalle.getColumnModel().getColumn(COL_CANT).setPreferredWidth(50);
			tableDetalle.getColumnModel().getColumn(COL_ARTICULO).setPreferredWidth(275);
			tableDetalle.getColumnModel().getColumn(COL_DIAS).setPreferredWidth(50);
			tableDetalle.getColumnModel().getColumn(COL_FECHA_DEVOLUCION).setPreferredWidth(125);
			tableDetalle.getColumnModel().getColumn(COL_PRECIO).setPreferredWidth(100);
			tableDetalle.getColumnModel().getColumn(COL_SUB_TOTAL).setPreferredWidth(100);
			
			tableDetalle.setNumericColumn(COL_CANT, Integer.class);
			
			JComboBox articuloComboBox = new JComboBox();
			ArticuloPersistence articuloPersistence = (ArticuloPersistence) NGFactoryBean.getInstance().getBean("articuloPersistence");
			List<Articulo> articulos = articuloPersistence.getAll();
			Collections.sort(articulos, new Comparator<Articulo>() {

				@Override
				public int compare(Articulo o1, Articulo o2) {
					return o1.toString().compareTo(o2.toString());
				}
			});
			for(Articulo articulo : articulos) {
				articuloComboBox.addItem(articulo);
			}
			
			tableDetalle.getColumn(COLUMN_NAMES[COL_ARTICULO]).setCellEditor(new DefaultCellEditor(articuloComboBox));
			
			tableDetalle.getColumn(COLUMN_NAMES[COL_DIAS]).setCellEditor(new DefaultCellEditor(new JComboBox(new Object[] { 1, 7, 15, 30 })));
			
			tableDetalle.setNumericColumn(COL_PRECIO, Double.class);
			
			tableDetalle.setNumericColumn(COL_SUB_TOTAL, Double.class);
			
			tableDetalle.setEditable(true);
			
			tableDetalle.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
			tableDetalle.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0), "selectNextColumnCell");
			
			tableDetalle.getModel().addTableModelListener(new TableModelListener() {
				
				@Override
				public void tableChanged(TableModelEvent e) {
					int row = e.getFirstRow();
					if(e.getColumn() == COL_DIAS && !llenando) {
						
						Integer dias = (Integer)AlquilerEditDialog.this.getTableDetalle().getValueAt(row, COL_DIAS);
						
						if(dias != null) {	
							Articulo articulo = (Articulo)AlquilerEditDialog.this.getTableDetalle().getValueAt(row, COL_ARTICULO); 
							if(articulo != null) {
								Double precio = null;
								
								switch(dias) {
								case 1:
									precio = articulo.getPrecioDia();
									break;
								case 7:
									precio = articulo.getPrecioSemana();
									break;
								case 15:
									precio = articulo.getPrecioQuincena();
									break;
								case 30:
									precio = articulo.getPrecioMes();
									break;
								}

								AlquilerEditDialog.this.getTableDetalle().setValueAt(precio, row, COL_PRECIO);
							}
							
							String fechaString = AlquilerEditDialog.this.getDatePickerFecha().getText();
							if(StringUtils.isNotBlank(fechaString)) {
								try {
									Calendar c = Calendar.getInstance();
									c.setTime(FORMATO_FECHA.parse(fechaString));
									
									c.add(Calendar.DAY_OF_MONTH, dias);
									
									AlquilerEditDialog.this.getTableDetalle().setValueAt(FORMATO_FECHA.format(c.getTime()), row, COL_FECHA_DEVOLUCION);
								} catch (ParseException e1) {
									JOptionPane.showMessageDialog(AlquilerEditDialog.this, "Error al parsear fecha de devolución.", "Error", JOptionPane.ERROR_MESSAGE);
								}								
							}
						}
					} else if(e.getColumn() == COL_PRECIO || e.getColumn() == COL_CANT) {
						Integer cantidad = (Integer)AlquilerEditDialog.this.getTableDetalle().getValueAt(row, COL_CANT);
						Double precio = (Double)AlquilerEditDialog.this.getTableDetalle().getValueAt(row, COL_PRECIO);
						
						Double total = null;
						if(cantidad != null && precio != null) {
							total = cantidad * precio;
						}
						AlquilerEditDialog.this.getTableDetalle().setValueAt(total, row, COL_SUB_TOTAL);
						
						AlquilerEditDialog.this.actualizarTotal();
					}
				}
			});
			
			tableDetalle.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
				
				@Override
				public void valueChanged(ListSelectionEvent e) {
					AlquilerEditDialog.this.getButtonEliminarDetalle().setEnabled(AlquilerEditDialog.this.getTableDetalle().getSelectedRowCount() > 0);
				}
			});
		}
		
		return tableDetalle;
	}
	
	private void actualizarTotal() {
		Double total = 0d;
		for(int i = 0; i < this.getTableDetalle().getRowCount(); i++) {
			Double totalDetalle = (Double)this.getTableDetalle().getValueAt(i, COL_SUB_TOTAL);
			
			if(totalDetalle != null) {
				total += totalDetalle;
			}
		}
		
		this.getTextFieldTotal().setText(FORMATO_TOTAL.format(total));
	}
	
	private JPanel createPanelDetalle() {
		JPanel panelDetalle = new JPanel(new GridBagLayout());
		
		panelDetalle.add(new JScrollPane(this.getTableDetalle(), JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER), new GridBagConstraints(0, 0, 2, 2, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
		
		panelDetalle.add(new JLabel("Total:"), new GridBagConstraints(0, 2, 1, 1, 1, 0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 5, 5, 5), 0, 0));
		panelDetalle.add(this.getTextFieldTotal(), new GridBagConstraints(1, 2, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
		
		panelDetalle.add(this.getButtonAgregarDetalle(), new GridBagConstraints(2, 0, 1, 1, 0, 0.5, GridBagConstraints.SOUTH, GridBagConstraints.NONE, new Insets(5, 0, 5, 5), 0, 0));
		panelDetalle.add(this.getButtonEliminarDetalle(), new GridBagConstraints(2, 1, 1, 1, 0, 0.5, GridBagConstraints.NORTH, GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
		
		panelDetalle.setBorder(BorderFactory.createTitledBorder("Detalle"));
		
		return panelDetalle;
	}
	
	private JButton getButtonAgregarDetalle() {
		if(buttonAgregarDetalle == null) {
			buttonAgregarDetalle = NGGUIUtils.createIconButton("icons/plus.png", this);
		}
		
		return buttonAgregarDetalle;
	}
	
	private JButton getButtonEliminarDetalle() {
		if(buttonEliminarDetalle == null) {
			buttonEliminarDetalle = NGGUIUtils.createIconButton("icons/cross.png", this);
			buttonEliminarDetalle.setEnabled(false);
		}
		
		return buttonEliminarDetalle;
	}
	
	private JTextField getTextFieldTotal() {
		if(textFieldTotal == null) {
			textFieldTotal = new JTextField(8);
			textFieldTotal.setEditable(false);
			textFieldTotal.setFocusable(false);

			textFieldTotal.setMinimumSize(textFieldTotal.getPreferredSize());
		}
		
		return textFieldTotal;
	}
	
	private AutoCompletionComboBox getComboBoxEstado() {
		if(comboBoxEstado == null) {
			comboBoxEstado = new AutoCompletionComboBox();
			
			comboBoxEstado.addItem(null);
			for(EstadoAlquiler estadoAlquiler : EstadoAlquiler.values()) {
				comboBoxEstado.addItem(estadoAlquiler);
			}
		}
		
		return comboBoxEstado;
	}
	
	private JTextArea getTextAreaObservaciones() {
		if(textAreaObservaciones == null) {
			textAreaObservaciones = new JTextArea();
			textAreaObservaciones.setLineWrap(true);
			textAreaObservaciones.setWrapStyleWord(true);
		}
		
		return textAreaObservaciones;
	}
	
	private JButton getButtonImprimirContrato() {
		if(buttonImprimirContrato == null) {
			buttonImprimirContrato = NGGUIUtils.createIconButton("icons/printer.png", this);
		}
		
		return buttonImprimirContrato;
	}
	
	
	@Override
	protected void populateDetailPanel(Alquiler instance) {
		this.llenando = true;
		
		this.getClienteSelectorField().setEntity(instance.getCliente());
		this.getDatePickerFecha().setText(FORMATO_FECHA.format(instance.getFecha()));
		this.getTextFieldDireccionObra().setText(instance.getDireccionObra());
		
		for(Detalle detalle : instance.getDetalles()) {
			this.getTableDetalle().addRow(new Object[] { detalle.getCantidad(), detalle.getArticulo(), detalle.getDias(), FORMATO_FECHA.format(detalle.getFechaDevolucion()), detalle.getPrecio(), detalle.getCantidad() * detalle.getPrecio() });
			
			int lastRow = this.getTableDetalle().getRowCount() - 1;
			this.getTableDetalle().setCellAlignment(lastRow, COL_FECHA_DEVOLUCION, SwingConstants.RIGHT);
			
			this.getTableDetalle().setEditable(true);
			this.getTableDetalle().setCellEditable(lastRow, COL_SUB_TOTAL, false);
		}
		this.actualizarTotal();

		this.getIdsDetalles().addAll(instance.getDetalles());
		
		this.getComboBoxEstado().setSelectedItem(instance.getEstadoAlquiler());
		this.getTextAreaObservaciones().setText(instance.getObservaciones());
		
		this.llenando = false;
	}

	@Override
	protected boolean validateInput() {
		boolean valid = true;
		
		if(StringUtils.isBlank(this.getDatePickerFecha().getText())) {
			JOptionPane.showMessageDialog(this, "El campo 'Fecha' es obligatorio.", "Error", JOptionPane.ERROR_MESSAGE);
			this.getDatePickerFecha().requestFocus();
			
			valid = false;
		} else if(this.getClienteSelectorField().getEntity() == null) {
			JOptionPane.showMessageDialog(this, "El campo 'Cliente' es obligatorio.", "Error", JOptionPane.ERROR_MESSAGE);
			this.getClienteSelectorField().requestFocus();
			
			valid = false;
		} else if(StringUtils.isBlank(this.getTextFieldDireccionObra().getText())) {
			JOptionPane.showMessageDialog(this, "El campo 'Dirección de la obra' es obligatorio.", "Error", JOptionPane.ERROR_MESSAGE);
			this.getTextFieldDireccionObra().requestFocus();
			
			valid = false;
		} else if(!this.validarDetalle()) {
			valid = false;
		} else if(this.getComboBoxEstado().getSelectedItem() == null) {
			JOptionPane.showMessageDialog(this, "El campo 'Estado' es obligatorio.", "Error", JOptionPane.ERROR_MESSAGE);
			this.getTextFieldDireccionObra().requestFocus();
			
			valid = false;
		}
		
		return valid;
	}
	
	private boolean validarDetalle() {
		boolean valid = true;
		
		for(int i = 0; i < this.getTableDetalle().getRowCount(); i++) {
			for(int j = 0; j < COLUMN_NAMES.length; j++) {
				if(this.getTableDetalle().getValueAt(i, j) == null) {
					JOptionPane.showMessageDialog(this, "El campo '" + COLUMN_NAMES[j] + "' es obligatorio.", "Error", JOptionPane.ERROR_MESSAGE);
					this.getTableDetalle().changeSelection(i, j, false, false);
					
					valid = false;					
					break;					
				}
				if(j == COL_FECHA_DEVOLUCION) {
					try {
						FORMATO_FECHA.parse((String)this.getTableDetalle().getValueAt(i, j));
					} catch (ParseException e) {
						JOptionPane.showMessageDialog(this, "El formato del campo '" + COLUMN_NAMES[j] + "' es inválido.", "Error", JOptionPane.ERROR_MESSAGE);
						this.getTableDetalle().changeSelection(i, j, false, false);
						
						valid = false;
						break;
					}
				}
			}
		}
		
		return valid;
	}

	@Override
	protected Alquiler createNewInstance() {
		return new Alquiler();
	}

	@Override
	protected void populateInstance(Alquiler instance) {
		instance.setCliente(this.getClienteSelectorField().getEntity());
		try {
			instance.setFecha(FORMATO_FECHA.parse(this.getDatePickerFecha().getText()));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		instance.setDireccionObra(this.getTextFieldDireccionObra().getText());
		instance.setEstadoAlquiler((EstadoAlquiler)this.getComboBoxEstado().getSelectedItem());
		instance.setObservaciones(this.getTextAreaObservaciones().getText());
		
		List<Detalle> detalles = new ArrayList<Detalle>();
		for(int i = 0; i < this.getTableDetalle().getRowCount(); i++) {
			Detalle detalle = null;
			
			if(i <= this.getIdsDetalles().size() - 1) {
				detalle = getIdsDetalles().get(i);
			} else {
				detalle = new Detalle();
			}
			
			detalle.setCantidad((Integer)this.getTableDetalle().getValueAt(i, COL_CANT));
			detalle.setArticulo((Articulo)this.getTableDetalle().getValueAt(i, COL_ARTICULO));
			detalle.setDias((Integer)this.getTableDetalle().getValueAt(i, COL_DIAS));
			try {
				detalle.setFechaDevolucion(FORMATO_FECHA.parse((String)this.getTableDetalle().getValueAt(i, COL_FECHA_DEVOLUCION)));
			} catch (ParseException e) {
				JOptionPane.showMessageDialog(this, "Error al parsear fecha de devolución.");
			}
			detalle.setPrecio((Double)this.getTableDetalle().getValueAt(i, COL_PRECIO));
			
			detalles.add(detalle);
		}
		instance.setDetalles(detalles);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		super.actionPerformed(e);
		
		if(e.getSource() == this.getButtonAgregarDetalle()) {
			this.getTableDetalle().addRow(null);
			int lastRow = this.getTableDetalle().getRowCount() - 1;
			this.getTableDetalle().getSelectionModel().setSelectionInterval(lastRow, lastRow);
			this.getTableDetalle().setCellAlignment(lastRow, COL_FECHA_DEVOLUCION, SwingConstants.RIGHT);
			this.getTableDetalle().setEditable(true);
			this.getTableDetalle().setCellEditable(lastRow, COL_SUB_TOTAL, false);
		} else if(e.getSource() == this.getButtonEliminarDetalle()) {
			if(JOptionPane.showConfirmDialog(this, "¿Está seguro que desea eliminar el artículo seleccionado?", "Eliminar artículo", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
				int selectedRow = this.getTableDetalle().getSelectedRow();
				if(selectedRow < this.getIdsDetalles().size()) {
					this.getIdsDetalles().remove(selectedRow);					
				}
				((NGTableModel)this.getTableDetalle().getModel()).removeRow(this.getTableDetalle().getSelectedRow());
				
				this.actualizarTotal();
			}
		} else if(e.getSource() == this.getButtonImprimirContrato()) {
			if(this.validateInput()) {
				Alquiler alquiler = this.createNewInstance();
				this.populateInstance(alquiler);
				
				Map<String, Object> parameters = new HashMap<String, Object>();
				
				parameters.put("empresa", alquiler.getCliente().getTipoCliente() == TipoCliente.EMPRESA);
				parameters.put("cliente", alquiler.getCliente());
				parameters.put("alquiler", alquiler);
				
				try {
					JasperReport report = JasperCompileManager.compileReport(ClassLoader.getSystemClassLoader().getResourceAsStream("reports/contrato.jrxml"));
					JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(alquiler.getDetalles());
					JasperPrint jasperPrint = JasperFillManager.fillReport(
							report, parameters, dataSource);
//					JasperViewer.viewReport(jasperPrint, false);
					
					JRViewer jrv = new JRViewer(jasperPrint); 
					JDialog viewer = new JDialog(this,"Vista previa", true); 
					viewer.setSize(800,600); 
					viewer.setLocationRelativeTo(null); 
					viewer.getContentPane().add(jrv);
					viewer.setVisible(true);
				} catch (JRException e1) {
					e1.printStackTrace();
					JOptionPane.showMessageDialog(this, "Ha ocurrido un error al generar el reporte. Por favor, comuníquese con el desarrollador de la aplicacón.", "Error", JOptionPane.ERROR_MESSAGE);
				}				
			}
		}
	}
	
	private List<Detalle> getIdsDetalles() {
		if(idsDetalles == null) {
			idsDetalles = new ArrayList<Detalle>();
		}
		
		return idsDetalles;
	}

}
